//=============================================================================
/**
 *
 *	@file		bug_select.c
 *	@brief		虫選択画面
 *	@author		hosaka genya
 *	@data		2008.10.28
 *
 */
//=============================================================================
#include "common.h"
#include "gflib/touchpanel.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/wipe.h"
#include "system/wordset.h"
#include "system/fontproc.h"
#include "system/touch_subwindow.h"
#include "system/snd_tool.h"
#include "system/pmfprint.h"
#include "poketool/poke_tool.h"
#include "poketool/pokeicon.h"
#include "application/app_tool.h"

#include "application/bug_select.h"
#include "bug_select_msg.h"

#include "msgdata/msg_bug_select.h"

#include "bug_select_gra.naix"

typedef struct BUGSLT_MAIN_WORK_tag * BUGSLT_MAIN_PTR;
typedef struct PLATE_WORK_tag * PLATE_PTR;
typedef struct PLATE_CNT_WORK_tag * PLATE_CNT_PTR;

//=============================================================================
/**
 *								定数定義
 */
//=============================================================================

//--------------------------------------------------------------
///	汎用定数
//==============================================================
enum
{
	BGPRI_OBJ = 2,
	FONT_PAL_SYSTEM = 15,

	CATS_DISTANCE = FX32_CONST( 524 ),	///< 回りこみ防止
	OBJ_NUM = 32,						///< とりあえずの上限

	// -- Plate --
	PLTPOS_STD_X = GX_LCD_SIZE_X/2,
	PLTPOS_STD_Y = 8*9,
	PLTPOS_DIFF_Y = 8*5,
	PLTPOS_ICON_OFS_X = -(5*8+4),
	PLTPOS_ICON_OFS_Y = -(1*8),
	PLTPOS_LCDOVER = 50, ///< 画面外の閾値

	// -- 選択肢 --
	YESNO_CHR_OFS = 200,
	YESNO_PAL_OFS = 6,
	YESNO_POS_X = 25,
	YESNO_POS_Y = 10,

	// -- HP Bar --
	HP_CHR_PALETTE = 0x0,
	HP_CHR_GREEN = 1 + 0x0,
	HP_CHR_YELLOW = 1 + 0x09,
	HP_CHR_RED = 1 + 0x12,
};


#define	COL_RED		( GF_PRINTCOLOR_MAKE( 3,  4,  0 ) )		// フォントカラー：赤
#define	COL_BLUE	( GF_PRINTCOLOR_MAKE( 7,  8,  0 ) )		// フォントカラー：青
// HPゲージ
#define WIN_HPBAR_SX (6)
#define WIN_HPBAR_SY (1)
#define HPBAR_DOTTO_CHR_MAX ( WIN_HPBAR_SX * WIN_HPBAR_SY )
#define HPBAR_DOTTO_MAX ( HPBAR_DOTTO_CHR_MAX * 8 )
#define HPBAR_CGX_SIZE (9 * 3)

//--------------------------------------------------------------
///	プレート内で管理するCAP ID
//==============================================================
enum
{
	PLTCAP_ID_BASE = 0,
	PLTCAP_ID_ICON,
	PLTCAP_ID_MAX,
};


//--------------------------------------------------------------
///	メインワークで管理するCAP ID
//==============================================================
enum
{
	MCAP_ID_ARROW = 0,
	MCAP_ID_MAX,
};

//--------------------------------------------------------------
/// Plate ID
//==============================================================
typedef enum
{
	PLATE_ID_FIRST = 0,
	PLATE_ID_SECOND,
	PLATE_ID_MAX,
} PLATE_ID;

//--------------------------------------------------------------
///	プレートの移動状態
//==============================================================
typedef enum
{
	PLATE_MOVE_NULL = 0,	///< 移動していない状態
	PLATE_MOVING,			///< 移動している状態
	PLATE_MOVE_MAX,
} PLATE_MOVE;


//--------------------------------------------------------------
///	Scene ID
//==============================================================
typedef enum
{
	SCENE_FIRST,
	SCENE_NORMAL,
	SCENE_MAX,
}SCENE;

//--------------------------------------------------------------
///	BG 設定
//==============================================================
#define BG_FRM_M_BASE (GF_BGL_FRAME0_M)
#define BG_FRM_M_TEXT (GF_BGL_FRAME1_M)
#define BG_FRM_M_PLT_0 (GF_BGL_FRAME2_M)
#define BG_FRM_M_PLT_1 (GF_BGL_FRAME3_M)
#define BG_FRM_S_BASE (GF_BGL_FRAME0_S)

#define BG_USE_NUM (5)
static const u8 c_BG_UseList[ BG_USE_NUM ] = {
	BG_FRM_M_BASE,	BG_FRM_M_TEXT, BG_FRM_M_PLT_0, BG_FRM_M_PLT_1,
	BG_FRM_S_BASE,
};


//--------------------------------------------------------------
///	OBJ RES ID
//==============================================================
enum {
	PAL_ID_M_MAIN,
	PAL_ID_M_POKEICON,
	PAL_ID_MAX,
};
enum {
	CHR_ID_M_MAIN,
	CHR_ID_M_POKEICON_0,
	CHR_ID_M_POKEICON_1,
	CHR_ID_MAX,
};
enum {
	CEL_ID_MAIN,
	CEL_ID_POKEICON,
	CEL_ID_MAX,
};
enum {
	ANM_ID_MAIN,
	ANM_ID_POKEICON,
	ANM_ID_MAX,
};

//--------------------------------------------------------------
///	プレートで管理するBMPWIN ID
//==============================================================
enum {
	PLTWIN_ID_NAME = 0,
	PLTWIN_ID_SEX,
	PLTWIN_ID_LV,
	PLTWIN_ID_HP,
	PLTWIN_ID_HPMAX,
	PLTWIN_ID_HPBAR,
	PLTWIN_ID_MAX,
};

//--------------------------------------------------------------
///	Plate内部のBMPWIN用データ
//==============================================================
typedef struct {
	s16 pos_x;	///< プレート基準座標からの差異(キャラ単位)
	s16 pos_y;	///< プレート基準座標からの差異(キャラ単位)
	u8 siz_x;
	u8 siz_y;
	u8 palnum;
	u16 chrnum;
} PLTWIN_DAT;

#define BMPSTR_H		(2)
#define BMPSTR_H_MINI	(1)
// ++ Width ++
#define PLTWIN_NAME_W	(8)
#define PLTWIN_SEX_W	(2)
#define PLTWIN_LV_W		(5)
#define PLTWIN_HP_W		(3)
#define PLTWIN_HPMAX_W	(5)
// ++ CGX ++
#define PLTWIN_NAME_CGX ( 1 + HPBAR_CGX_SIZE )
#define PLTWIN_SEX_CGX	(PLTWIN_NAME_CGX	+ PLTWIN_NAME_W * BMPSTR_H )
#define PLTWIN_LV_CGX	(PLTWIN_SEX_CGX		+ PLTWIN_SEX_W * BMPSTR_H )
#define PLTWIN_HP_CGX	(PLTWIN_LV_CGX		+ PLTWIN_LV_W * BMPSTR_H_MINI )
#define PLTWIN_HPMAX_CGX (PLTWIN_HP_CGX		+ PLTWIN_HP_W * BMPSTR_H_MINI )
#define PLTWIN_HPBAR_CGX (PLTWIN_HPMAX_CGX	+ PLTWIN_HPMAX_W * BMPSTR_H_MINI )

// ++ plate bmpwin data table ++
static const PLTWIN_DAT c_PlateWinList[ PLTWIN_ID_MAX ] =
{
	{	-2,	-2,	PLTWIN_NAME_W,	BMPSTR_H,		FONT_PAL_SYSTEM, PLTWIN_NAME_CGX },
	{	5,	-2,	PLTWIN_SEX_W,	BMPSTR_H,		FONT_PAL_SYSTEM, PLTWIN_SEX_CGX },
	{	-8,	1,	PLTWIN_LV_W,	BMPSTR_H_MINI,	FONT_PAL_SYSTEM, PLTWIN_LV_CGX },
	{	-2,	1,	PLTWIN_HP_W,	BMPSTR_H_MINI,	FONT_PAL_SYSTEM, PLTWIN_HP_CGX },
	{	1,	1,	PLTWIN_HPMAX_W,	BMPSTR_H_MINI,	FONT_PAL_SYSTEM, PLTWIN_HPMAX_CGX },
	{	0,	0,	WIN_HPBAR_SX,	WIN_HPBAR_SY,	FONT_PAL_SYSTEM, PLTWIN_HPBAR_CGX },
};

//=============================================================================
/**
 *								構造体定義
 */
//=============================================================================
//--------------------------------------------------------------
///	プレートワーク
//==============================================================
typedef struct PLATE_WORK_tag {
	POKEMON_PARAM* pp;
	CATS_ACT_PTR cap[ PLTCAP_ID_MAX ];
	GF_BGL_BMPWIN win[ PLTWIN_ID_MAX ];
	PLATE_MOVE move;
	s16 tar_y;
	s16 pos_x;
	s16 pos_y;
} PLATE_WORK;

//--------------------------------------------------------------
/// プレート管理ワーク
//==============================================================
typedef struct PLATE_CNT_WORK_tag {
	// [in]
	HEAPID HeapID;
	GF_BGL_INI* bgl;
	MSG_CNT_PTR	msg_cnt;
	CATS_SYS_PTR csp;
	CATS_RES_PTR crp;
	s8 icon_pltt_ofs;
	// [private]
	PLATE_PTR plate[ PLATE_ID_MAX ];
} PLATE_CNT_WORK;

//--------------------------------------------------------------
///	メインワーク
//==============================================================
typedef struct BUGSLT_MAIN_WORK_tag {
	HEAPID HeapID;
	BUG_SELECT_PROC_PARAM* prm;
	GF_BGL_INI		*bgl;
	CATS_SYS_PTR	csp;
	CATS_RES_PTR	crp;
	CATS_ACT_PTR	cap[ MCAP_ID_MAX ];
	TOUCH_SW_SYS*	sw_sys;

	ARCHANDLE*		arc_main;
	PLATE_CNT_PTR	plt_cnt;	///< Plate Controller
	MSG_CNT_PTR		msg_cnt;

	s8 icon_pltt_ofs;
	int scene;
	int seq;
} BUGSLT_MAIN_WORK;

//=============================================================================
/**
 *							プロトタイプ宣言
 */
//=============================================================================
//-- prototype --
// ++ Scene Func ++
static BOOL SceneFunc_First( BUGSLT_MAIN_PTR ptr );
static BOOL SceneFunc_Normal( BUGSLT_MAIN_PTR ptr );
// Func Pointer table
static BOOL (*MainFuncTbl[])() =
{
	SceneFunc_First,
	SceneFunc_Normal,
};

// ++ Scene Sub Func ++
static void SceneNormal_Init( BUGSLT_MAIN_PTR ptr );
static void SceneNormal_StartYesNo( BUGSLT_MAIN_PTR ptr );
// +++ Common Func ++
static u8 GetScene( u8 prm );
static void SetVramBank(void);
static void VramDispInit( void );
static void SetReturnData( BUGSLT_MAIN_PTR ptr, u8 idx );
static void BmpWin_SetHpBar( GF_BGL_BMPWIN* win, u16 hp, u16 mhp );
// ++ Common Util ++
static void Common_Vblank( void* work );
static void Common_Init( PROC* proc );
static void Common_End( PROC* proc );
// ++ BG Util ++
static void BG_Init( BUGSLT_MAIN_PTR ptr );
static void BG_Release( BUGSLT_MAIN_PTR ptr );
static void BG_LoadRes( BUGSLT_MAIN_PTR ptr );
// ++ CATS Util ++
static void CATS_Create( BUGSLT_MAIN_PTR ptr );
static void CATS_Release( CATS_SYS_PTR csp, CATS_RES_PTR crp );
static void CATS_LoadRes( BUGSLT_MAIN_PTR ptr );
static void CATS_TransPokeIcon( CATS_ACT_PTR cap, POKEMON_PARAM* pp, s8 pal_ofs, HEAPID HeapID );
static void CATS_CgxChangeTrans( CATS_ACT_PTR cap, u8 * buf, u32 siz );
static CATS_ACT_PTR CATS_AddCommon( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 pos_x, s16 pos_y, u8 anm, u8 pri );
static CATS_ACT_PTR CATS_AddIcon( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 pos_x, s16 pos_y, u8 idx );
// ++ Plate ++
static PLATE_PTR Plate_Create( PLATE_CNT_PTR cnt, s16 pos_x, s16 pos_y, PLATE_ID idx, POKEMON_PARAM* pp );
static void Plate_Delete( PLATE_PTR plt );
static void Plate_Print( PLATE_PTR plt, MSG_CNT_PTR msg_cnt );
static void Plate_MoveProc( PLATE_PTR plt );
static BOOL Plate_MoveCheck( PLATE_PTR plt );
// ++ Plate Controller ++
static PLATE_CNT_PTR PlateCnt_Create( HEAPID HeapID, GF_BGL_INI* bgl, MSG_CNT_PTR msg_cnt, CATS_SYS_PTR csp, CATS_RES_PTR crp, s8 icon_pltt_ofs );
static void PlateCnt_Delete( PLATE_CNT_PTR cnt );
static void PlateCnt_Add( PLATE_CNT_PTR cnt, PLATE_ID idx, s16 pos_x, s16 pos_y, POKEMON_PARAM* pp );
static void PlateCnt_MoveStart( PLATE_CNT_PTR cnt, PLATE_ID idx, PLATE_MOVE move, s16 tar_y );
static void PlateCnt_MoveProc( PLATE_CNT_PTR cnt );
static BOOL PlateCnt_MoveCheck( PLATE_CNT_PTR cnt );

//=============================================================================
/**
 *								外部公開関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	PROC 初期化
 *
 *	@param	PROC* proc
 *	@param	seq
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
extern PROC_RESULT BugSelectProc_Init( PROC* proc, int* seq )
{
	switch( *seq )
	{
		case 0:
			Common_Init( proc );
			(*seq)++;
			break;

		case 1:
			{
				BUGSLT_MAIN_PTR ptr = PROC_GetWork(proc);
				WIPE_SYS_Start( WIPE_PATTERN_WMS, WIPE_TYPE_FADEIN, WIPE_TYPE_FADEIN,
							WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, ptr->HeapID );
			}
			(*seq)++;
			break;

		case 2:
			if( WIPE_SYS_EndCheck() )
			{
				(*seq) = 0;
				HOSAKA_PRINT("Proc Init Finish\n");
				return PROC_RES_FINISH;
			}
			break;

		default : GF_ASSERT(0);
	}

	return PROC_RES_CONTINUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	PROC 終了
 *
 *	@param	PROC* proc
 *	@param	seq
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
extern PROC_RESULT BugSelectProc_End( PROC* proc, int* seq )
{
	BUGSLT_MAIN_PTR ptr = PROC_GetWork(proc);

	switch( *seq )
	{
		case 0:
			WIPE_SYS_Start( WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT,
							WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, ptr->HeapID );
			(*seq)++;
			break;

		case 1:
			if( WIPE_SYS_EndCheck() )
			{
				Common_End( proc );
				HOSAKA_PRINT("Proc End Finish\n");
				return PROC_RES_FINISH;
			}
			break;

		default : GF_ASSERT(0);
	}

	return PROC_RES_CONTINUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	PROC メイン
 *
 *	@param	PROC* proc
 *	@param	seq
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
extern PROC_RESULT BugSelectProc_Main( PROC* proc, int* seq )
{
	BUGSLT_MAIN_PTR ptr = PROC_GetWork(proc);

	GF_ASSERT( ptr );

	if( MainFuncTbl[ ptr->scene ]( ptr ) )
	{
		return PROC_RES_FINISH;
	}

	return PROC_RES_CONTINUE;
}


//=============================================================================
/**
 *								static関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	Scene:虫取得(初回)
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval	TRUE : 終了
 */
//-----------------------------------------------------------------------------
static BOOL SceneFunc_First( BUGSLT_MAIN_PTR ptr )
{
	enum
	{
		FIRST_INIT,
		FIRST_MSG_WAIT,
		FIRST_INPUT_WAIT,
		FIRST_EXIT,
	};

	int code = MSG_ID_NONE;
	WORDSET* wset = MSG_CNT_GetWordSet( ptr->msg_cnt );

	if( MSG_CNT_Main( ptr->msg_cnt ) ){ return FALSE; }

	switch( ptr->seq )
	{
		case FIRST_INIT :
			// プレート追加
			{
				POKEMON_PARAM* pp = ptr->prm->pPoke[ PLATE_ID_FIRST ];
				PlateCnt_Add( ptr->plt_cnt, PLATE_ID_FIRST, PLTPOS_STD_X, PLTPOS_STD_Y , pp );

				// ポケモン名登録
				WORDSET_RegisterPokeMonsName( wset, 0, PPPPointerGet(pp) );
			}

			code = msg_park_hokaku_talk_01; // つかまえた！
			ptr->seq = FIRST_INPUT_WAIT;
			break;

		case FIRST_MSG_WAIT :
			// メッセージ表示待ち
			if( MSG_CNT_Main( ptr->msg_cnt ) == FALSE )
			{
				ptr->seq = FIRST_INPUT_WAIT;
			}
			break;

		case FIRST_INPUT_WAIT :
			// キー入力待ち
			if( GF_TP_GetTrg() || sys.trg & PAD_BUTTON_DECIDE )
			{
				Snd_SePlay( SEQ_SE_DP_SELECT );
				ptr->seq = FIRST_EXIT;
			}
			break;

		case FIRST_EXIT :
			return TRUE;

		default : GF_ASSERT(0);
	}

	if( code != MSG_ID_NONE ){ MSG_CNT_PrintMessage( ptr->msg_cnt, code ); }

	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	Scene:虫選択(二回目以降)
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval	TRUE : 終了
 */
//-----------------------------------------------------------------------------
static BOOL SceneFunc_Normal( BUGSLT_MAIN_PTR ptr )
{
	enum
	{
		NORMAL_INIT,
		NORMAL_YESNO_START,
		NORMAL_YESNO_WAIT,

		NORMAL_RES_YES,
		NORMAL_RES_NO,

		NORMAL_INPUT_WAIT,

		NORMAL_EXIT,
	};

	int code = MSG_ID_NONE;
	WORDSET* wset = MSG_CNT_GetWordSet( ptr->msg_cnt );

	if( MSG_CNT_Main( ptr->msg_cnt ) ){ return FALSE; }

	switch( ptr->seq )
	{
		case NORMAL_INIT :
			code = msg_park_hokaku_talk_02; // どっちにする？
			SceneNormal_Init( ptr );
			ptr->seq = NORMAL_YESNO_START;
			break;

		case NORMAL_YESNO_START :
			SceneNormal_StartYesNo( ptr );
			ptr->seq = NORMAL_YESNO_WAIT;
			break;

		case NORMAL_YESNO_WAIT :
			{
				int ret = TOUCH_SW_Main( ptr->sw_sys );

				switch( ret )
				{
					case TOUCH_SW_RET_YES :
						TOUCH_SW_Reset( ptr->sw_sys );
						CATS_ObjectEnableCap( ptr->cap[ MCAP_ID_ARROW ], FALSE );
						PlateCnt_MoveStart( ptr->plt_cnt, PLATE_ID_FIRST, PLATE_MOVING, PLTPOS_STD_Y );
						PlateCnt_MoveStart( ptr->plt_cnt, PLATE_ID_SECOND, PLATE_MOVING, GX_LCD_SIZE_Y + PLTPOS_LCDOVER );
						SetReturnData( ptr, TOUCH_SW_RET_YES );
						ptr->seq = NORMAL_RES_YES;
						break;
					case TOUCH_SW_RET_NO :
						TOUCH_SW_Reset( ptr->sw_sys );
						CATS_ObjectEnableCap( ptr->cap[ MCAP_ID_ARROW ], FALSE );
						PlateCnt_MoveStart( ptr->plt_cnt, PLATE_ID_FIRST, PLATE_MOVING, - PLTPOS_LCDOVER );
						PlateCnt_MoveStart( ptr->plt_cnt, PLATE_ID_SECOND, PLATE_MOVING, PLTPOS_STD_Y );
						SetReturnData( ptr, TOUCH_SW_RET_NO );
						ptr->seq = NORMAL_RES_NO;
						break;
				}
			}
			break;

		case NORMAL_RES_YES :
			// 移動
			PlateCnt_MoveProc( ptr->plt_cnt );
			// 移動待ち
			if( PlateCnt_MoveCheck( ptr->plt_cnt ) )
			{
				code = msg_park_hokaku_talk_03;
				ptr->seq = NORMAL_INPUT_WAIT;
			}
			break;

		case NORMAL_RES_NO :
			// 移動
			PlateCnt_MoveProc( ptr->plt_cnt );
			// 移動待ち
			if( PlateCnt_MoveCheck( ptr->plt_cnt ) )
			{
				code = msg_park_hokaku_talk_04;
				ptr->seq = NORMAL_INPUT_WAIT;
			}
			break;

		case NORMAL_INPUT_WAIT :
			// キー入力待ち
			if( GF_TP_GetTrg() || sys.trg & PAD_BUTTON_DECIDE )
			{
				Snd_SePlay( SEQ_SE_DP_SELECT );
				ptr->seq = NORMAL_EXIT;
			}
			break;

		case NORMAL_EXIT :
			return TRUE;

		default : GF_ASSERT(0);
	}

	if( code != MSG_ID_NONE ){ MSG_CNT_PrintMessage( ptr->msg_cnt, code ); }

	return FALSE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	虫選択:初期化
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SceneNormal_Init( BUGSLT_MAIN_PTR ptr )
{
	WORDSET* wset = MSG_CNT_GetWordSet( ptr->msg_cnt );
	POKEMON_PARAM* pp1 = ptr->prm->pPoke[0];
	POKEMON_PARAM* pp2 = ptr->prm->pPoke[1];

	PlateCnt_Add( ptr->plt_cnt, PLATE_ID_FIRST, PLTPOS_STD_X, PLTPOS_STD_Y - PLTPOS_DIFF_Y, pp1 );
	PlateCnt_Add( ptr->plt_cnt, PLATE_ID_SECOND, PLTPOS_STD_X, PLTPOS_STD_Y + PLTPOS_DIFF_Y, pp2 );

	// ポケモン名登録
	WORDSET_RegisterPokeMonsName( wset, 0, PPPPointerGet(pp1) );
	WORDSET_RegisterPokeMonsName( wset, 1, PPPPointerGet(pp2) );

	// 矢印追加
	ptr->cap[ MCAP_ID_ARROW ] = CATS_AddCommon( ptr->csp, ptr->crp, PLTPOS_STD_X, PLTPOS_STD_Y, 1, 0 );
	CATS_ObjectPaletteSetCap( ptr->cap[ MCAP_ID_ARROW ], 1 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	虫選択:選択肢表示
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SceneNormal_StartYesNo( BUGSLT_MAIN_PTR ptr )
{
	TOUCH_SW_PARAM param = {0};

	param.p_bgl = ptr->bgl;
	param.bg_frame = BG_FRM_M_TEXT;
	param.char_offs = YESNO_CHR_OFS;
	param.pltt_offs = YESNO_PAL_OFS;
	param.x = YESNO_POS_X;
	param.y = YESNO_POS_Y;
	param.key_pos = 0;
	TOUCH_SW_Init( ptr->sw_sys, &param );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	シーンを取得
 *
 *	@param	u8 prm	SCENE Enum
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static u8 GetScene( u8 prm )
{
	switch(prm)
	{
		case 0 : return SCENE_NORMAL;
		case 1 : return SCENE_FIRST;
		default : GF_ASSERT(0);
	}
	GF_ASSERT(0);
	return 0;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	Vramを設定
 *
 *	@param	none
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void SetVramBank(void)
{
	GF_BGL_DISPVRAM tbl = {
		GX_VRAM_BG_128_B,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット

		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット

		GX_VRAM_OBJ_128_A,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット

		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット

		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &tbl );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	VramDisp初期化
 *
 *	@param	void
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void VramDispInit( void )
{
	sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
	sys_HBlankIntrStop();

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane( 0 );
	GXS_SetVisiblePlane( 0 );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	PARAMに値を返す
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *	@param	idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void SetReturnData( BUGSLT_MAIN_PTR ptr, u8 idx )
{
	switch( idx )
	{
		case TOUCH_SW_RET_YES :
			ptr->prm->pResPoke = ptr->prm->pPoke[0];
			break;

		case TOUCH_SW_RET_NO :
			ptr->prm->pResPoke = ptr->prm->pPoke[1];
			break;

		default : GF_ASSERT(0);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * HPゲージ表示
 *
 *	@param	GF_BGL_BMPWIN* win
 *	@param	hp
 *	@param	mhp
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void BmpWin_SetHpBar( GF_BGL_BMPWIN* win, u16 hp, u16 mhp )
{
	u8	i;
	GF_BGL_INI* bgl;
	u8 frm;
	u16	chr;
	u8 dot;
	u8 px, py;

	// 情報取得
	bgl = GF_BGL_BmpWinGet_BglIni( win );
	frm = GF_BGL_BmpWinGet_Frame( win );
	px = GF_BGL_BmpWinGet_PosX( win );
	py = GF_BGL_BmpWinGet_PosY( win );
	dot = GetNumDotto( hp, mhp, HPBAR_DOTTO_MAX );

	HOSAKA_PRINT("BAR dot:%d px:%d, py:%d \n",dot, px, py);

	// カラー設定
	switch( GetHPGaugeDottoColor( hp, mhp, HPBAR_DOTTO_MAX ) )
	{
		case HP_DOTTO_MAX :
		case HP_DOTTO_GREEN :
		case HP_DOTTO_NULL :
			chr = HP_CHR_GREEN | HP_CHR_PALETTE;
			break;

		case HP_DOTTO_YELLOW :
			chr = HP_CHR_YELLOW | HP_CHR_PALETTE;
			break;

		case HP_DOTTO_RED :
			chr = HP_CHR_RED | HP_CHR_PALETTE;
			break;

		default : GF_ASSERT(0);
	}

	// スクリーン書き換え
	for( i=0; i<HPBAR_DOTTO_CHR_MAX; i++ )
	{
		u16	cgx;

		if( dot >= 8 ){
			cgx = chr + 8;
		}else{
			cgx = chr + dot;
		}

		GF_BGL_ScrFill( bgl, frm, cgx, px + i, py, 1, 1, GF_BGL_SCRWRT_PALIN );

		if( dot < 8 ){
			dot = 0;
		}else{
			dot -= 8;
		}
	}

	// スクリーン転送
	GF_BGL_LoadScreenV_Req( bgl, frm );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	VBlank処理
 *
 *	@param	void* work
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void Common_Vblank( void* work )
{
	BUGSLT_MAIN_PTR ptr = work;

	GF_ASSERT( ptr );
	GF_ASSERT( ptr->crp );
	GF_ASSERT( ptr->bgl );

	CATS_Draw( ptr->crp );
	CATS_RenderOamTrans();
	GF_BGL_VBlankFunc( ptr->bgl );

	OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	汎用初期化処理
 *
 *	@param	PROC* proc
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Common_Init( PROC* proc )
{
	BUGSLT_MAIN_PTR ptr = NULL;
	BUG_SELECT_PROC_PARAM* p_prm;

	p_prm = (BUG_SELECT_PROC_PARAM*)PROC_GetParentWork( proc );

	GF_ASSERT( p_prm );

	// ヒープ生成
	sys_CreateHeap( HEAPID_BASE_APP, HEAPID_BUG_SELECT, 0x30000 );

	ptr = PROC_AllocWork( proc, sizeof(BUGSLT_MAIN_WORK), HEAPID_BUG_SELECT );
	MI_CpuClear8( ptr, sizeof(BUGSLT_MAIN_WORK) );

	// メンバ初期化
	ptr->HeapID = HEAPID_BUG_SELECT;
	ptr->prm = p_prm;
	ptr->scene = GetScene( p_prm->bFirstGet );

	VramDispInit();

	GX_SetDispSelect( GX_DISP_SELECT_SUB_MAIN );

	SetVramBank();

	// BG
	BG_Init(ptr);
	BG_LoadRes(ptr);

	// OBJ
	CATS_Create(ptr);
	CATS_LoadRes(ptr);

	// TOUCH_SW 生成
	ptr->sw_sys = TOUCH_SW_AllocWork( ptr->HeapID );

	// Message
	ptr->msg_cnt = MSG_CNT_Create( ptr->HeapID );
	MSG_CNT_Init( ptr->msg_cnt, ptr->bgl, BG_FRM_M_TEXT, p_prm->cfg );

	// プレート管理ワーク生成
	ptr->plt_cnt = PlateCnt_Create( ptr->HeapID, ptr->bgl, ptr->msg_cnt, ptr->csp, ptr->crp, ptr->icon_pltt_ofs );

	WIPE_ResetWndMask( WIPE_DISP_MAIN );
	WIPE_ResetWndMask( WIPE_DISP_SUB );

	MsgPrintSkipFlagSet(MSG_SKIP_ON);
	MsgPrintTouchPanelFlagSet(MSG_TP_ON);

	sys_VBlankFuncChange( Common_Vblank, ptr );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	汎用終了処理
 *
 *	@param	PROC* proc
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Common_End( PROC* proc )
{
	BUGSLT_MAIN_PTR ptr = PROC_GetWork(proc);

	TOUCH_SW_FreeWork( ptr->sw_sys );
	PlateCnt_Delete( ptr->plt_cnt );
	MSG_CNT_Delete( ptr->msg_cnt );

	// MAIN CAP 消去
	{
		int i;
		for( i=0; i<MCAP_ID_MAX; i++ )
		{
			if( ptr->cap[i] != NULL )
			{
				CATS_ActorPointerDelete_S( ptr->cap[i] );
				ptr->cap[i] = NULL;
			}
		}
	}

	CATS_Release( ptr->csp, ptr->crp );
	BG_Release(ptr);

	VramDispInit();

	PROC_FreeWork( proc );
	sys_DeleteHeap( HEAPID_BUG_SELECT );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BG 初期化
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BG_Init( BUGSLT_MAIN_PTR ptr )
{
	ptr->bgl = GF_BGL_BglIniAlloc( ptr->HeapID );

	{	//BG SYSTEM
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_0,GX_BG0_AS_2D
		};
		GF_BGL_InitBG(&BGsys_data);
	}

	{
		int i;
		GF_BGL_BGCNT_HEADER TextBgCntDat[ BG_USE_NUM ] = {
			// -- MAIN --
			{	// BG_FRM_M_BASE BG0
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0000,GX_BG_CHARBASE_0x04000,GX_BG_EXTPLTT_01,
				3,0,0,FALSE
			},
			{	// BG_FRM_M_TEXT BG1
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x0800,GX_BG_CHARBASE_0x08000,GX_BG_EXTPLTT_01,
				0,0,0,FALSE
			},
			{	// BG_FRM_M_PLT_0 BG2
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x1000,GX_BG_CHARBASE_0x0c000,GX_BG_EXTPLTT_01,
				1,0,0,FALSE
			},
			{	// BG_FRM_M_PLT_1 BG3
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0x1800,GX_BG_CHARBASE_0x10000,GX_BG_EXTPLTT_01,
				1,0,0,FALSE
			},
			// -- SUB --
			{	// BG_FRM_S_BASE BG0
				0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
				GX_BG_SCRBASE_0xf800,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
				2,0,0,FALSE
			},
		};

		for(i = 0;i < BG_USE_NUM;i++){
			GF_BGL_BGControlSet( ptr->bgl, c_BG_UseList[i], &(TextBgCntDat[i]), GF_BGL_MODE_TEXT );
			GF_BGL_ScrClear( ptr->bgl, c_BG_UseList[i] );
			GF_BGL_CharFill( ptr->bgl, c_BG_UseList[i], 0, 1, 0 );
		}
	}

	ptr->arc_main = ArchiveDataHandleOpen( ARC_BUG_SELECT_GRA, ptr->HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BG 開放
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BG_Release( BUGSLT_MAIN_PTR ptr )
{
	int i;
	ArchiveDataHandleClose( ptr->arc_main );

	for( i=0; i<BG_USE_NUM; i++ )
	{
		GF_BGL_BGControlExit( ptr->bgl, c_BG_UseList[i] );
	}

	sys_FreeMemoryEz( ptr->bgl );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	BG 展開
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void BG_LoadRes( BUGSLT_MAIN_PTR ptr )
{
	enum
	{
		PAL_SIZE = 0x20 * 16,
	};

	GF_ASSERT( ptr->bgl );

	//=====================================================
	// Main LCD
	//=====================================================
	// -- pal --
	ArcUtil_HDL_PalSet( ptr->arc_main, NARC_bug_select_gra_bg_nclr, PALTYPE_MAIN_BG,
			0, PAL_SIZE, ptr->HeapID );

	// -- base --
	ArcUtil_HDL_BgCharSet( ptr->arc_main, NARC_bug_select_gra_bg_lz_ncgr, ptr->bgl,
			BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	ArcUtil_HDL_ScrnSet( ptr->arc_main, NARC_bug_select_gra_bg_m_lz_nscr, ptr->bgl,
			BG_FRM_M_BASE, 0, 0, TRUE, ptr->HeapID );

	// -- プレート用領域 --
	ArcUtil_HDL_BgCharSet( ptr->arc_main, NARC_bug_select_gra_bg_plate_lz_ncgr, ptr->bgl,
			BG_FRM_M_PLT_0, 1, 0, TRUE, ptr->HeapID );

	ArcUtil_HDL_BgCharSet( ptr->arc_main, NARC_bug_select_gra_bg_plate_lz_ncgr, ptr->bgl,
			BG_FRM_M_PLT_1, 1, 0, TRUE, ptr->HeapID );

	//=====================================================
	// Sub LCD
	//=====================================================
	// -- pal --
	ArcUtil_HDL_PalSet( ptr->arc_main, NARC_bug_select_gra_bg_nclr, PALTYPE_SUB_BG,
			0, PAL_SIZE, ptr->HeapID );

	// -- base --
	ArcUtil_HDL_BgCharSet( ptr->arc_main, NARC_bug_select_gra_bg_lz_ncgr, ptr->bgl,
			BG_FRM_S_BASE, 0, 0, TRUE, ptr->HeapID );

	ArcUtil_HDL_ScrnSet( ptr->arc_main, NARC_bug_select_gra_bg_s_lz_nscr, ptr->bgl,
			BG_FRM_S_BASE, 0, 0, TRUE, ptr->HeapID );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CATS 生成
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CATS_Create( BUGSLT_MAIN_PTR ptr )
{
	ptr->csp = CATS_AllocMemory( ptr->HeapID );
	ptr->crp = CATS_ResourceCreate( ptr->csp );

	{
		TCATS_OAM_INIT	coi = {
			0, 128,
			0, 32,
			0, 128,
			0, 32,
		};

		TCATS_CHAR_MANAGER_MAKE ccmm = {
			0,	// dummy
			1024*128,
			1024*16,
			GX_OBJVRAMMODE_CHAR_1D_64K,
			GX_OBJVRAMMODE_CHAR_1D_64K,
		};

		ccmm.num = OBJ_NUM;

		CATS_SystemInit( ptr->csp, &coi, &ccmm, 32 );
	}

	CATS_ClactSetInit( ptr->csp, ptr->crp, OBJ_NUM );

	{
		TCATS_RESOURCE_NUM_LIST crnl = { CHR_ID_MAX, PAL_ID_MAX, CEL_ID_MAX, ANM_ID_MAX, 0 };
		CATS_ResourceManagerInit( ptr->csp, ptr->crp, &crnl );
	}

	//サブサーフェースの距離を設定
	CLACT_U_SetSubSurfaceMatrix( CATS_EasyRenderGet( ptr->csp ), 0, CATS_DISTANCE );

	GF_Disp_GX_VisibleControl(  GX_PLANEMASK_OBJ, VISIBLE_ON );		// MAIN DISP OBJ ON
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// SUB DISP OBJ ON
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CATS 開放
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CATS_Release( CATS_SYS_PTR csp, CATS_RES_PTR crp )
{
	CATS_ResourceDestructor_S(csp, crp);
	CATS_FreeMemory(csp);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CATS リソースロード
 *
 *	@param	BUGSLT_MAIN_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CATS_LoadRes( BUGSLT_MAIN_PTR ptr )
{
	CATS_SYS_PTR csp = ptr->csp;
	CATS_RES_PTR crp = ptr->crp;

	CATS_LoadResourcePlttArcH( csp, crp, ptr->arc_main,
			NARC_bug_select_gra_obj_nclr, 0, 2, NNS_G2D_VRAM_TYPE_2DMAIN, PAL_ID_M_MAIN );

	CATS_LoadResourceCharArcH( csp, crp, ptr->arc_main,
			NARC_bug_select_gra_obj_lz_ncgr, TRUE, NNS_G2D_VRAM_TYPE_2DMAIN, CHR_ID_M_MAIN );

	CATS_LoadResourceCellArcH( csp, crp, ptr->arc_main,
			NARC_bug_select_gra_obj_lz_ncer, TRUE, CEL_ID_MAIN );

	CATS_LoadResourceCellAnmArcH( csp, crp,  ptr->arc_main,
			NARC_bug_select_gra_obj_lz_nanr, TRUE, ANM_ID_MAIN );

	// -- pokeicon res --
	{

		int i;
		ARCHANDLE* hdl = ArchiveDataHandleOpen( ARC_POKEICON, ptr->HeapID );

		for( i=0; i<PLATE_ID_MAX; i++ )
		{
			CATS_LoadResourceCharArcH(
					csp, crp, ptr->arc_main, NARC_bug_select_gra_pokeicon_dmy_64K_ncgr,
					FALSE, NNS_G2D_VRAM_TYPE_2DMAIN, CHR_ID_M_POKEICON_0 + i );
		}

		ptr->icon_pltt_ofs = CATS_LoadResourcePlttArcH( csp, crp, hdl, PokeIconPalArcIndexGet(),
								0, POKEICON_PAL_MAX, NNS_G2D_VRAM_TYPE_2DMAIN, PAL_ID_M_POKEICON );

		CATS_LoadResourceCellArcH( csp, crp, hdl, PokeIcon64kCellArcIndexGet(), FALSE, CEL_ID_POKEICON );
		CATS_LoadResourceCellAnmArcH( csp, crp, hdl, PokeIcon64kCellAnmArcIndexGet(), FALSE, ANM_ID_POKEICON );

		ArchiveDataHandleClose( hdl );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	指定CAPにポケアイコンを転送
 *
 *	@param	CATS_ACT_PTR cap
 *	@param	POKEMON_PARAM* pp
 *	@param	pal_ofs
 *	@param	HeapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CATS_TransPokeIcon( CATS_ACT_PTR cap, POKEMON_PARAM* pp, s8 pal_ofs, HEAPID HeapID )
{
	enum{ POKEICON_CGX_SIZE = 0x20*4*4*2 };

	ARCHANDLE* hdl;
	int arc;
	void* buf;
	NNSG2dCharacterData* p_chr;

	hdl = ArchiveDataHandleOpen( ARC_POKEICON, HeapID );

	arc = PokeIconCgxArcIndexGetByPP(pp);
	buf = ArcUtil_HDL_CharDataGet( hdl, arc, FALSE, &p_chr, HeapID );
	CATS_CgxChangeTrans( cap, p_chr->pRawData, POKEICON_CGX_SIZE );
	sys_FreeMemoryEz( buf );

	// パレット設定
	{
		u8 ofs = PokeIconPalNumGetByPP( pp ) + pal_ofs;
		CATS_ObjectPaletteSetCap( cap, ofs );
	}

	// アニメ設定
	CATS_ObjectAnimeSeqSetCap( cap, POKEICON_ANM_HPMAX );
	CATS_ObjectAutoAnimeSpeedSetCap( cap, FX32_ONE );
	CATS_ObjectAutoAnimeSetCap( cap, TRUE );

	ArchiveDataHandleClose(hdl);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJに割り当てられているキャラデータ（CGX）を書き換える
 *
 *	@param	cap
 *	@param	* buf
 *	@param	siz
 *	@param	b_LCD_main
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void CATS_CgxChangeTrans( CATS_ACT_PTR cap, u8 * buf, u32 siz )
{
	NNSG2dImageProxy * ipc;
	u32	cgx;
	NNS_G2D_VRAM_TYPE vram_type;

	vram_type = CLACT_VramTypeGet( cap->act );
	ipc = CLACT_ImageProxyGet( cap->act );
	cgx = NNS_G2dGetImageLocation( ipc, vram_type );

	DC_FlushRange( buf, siz );

	switch( vram_type )
	{
		case NNS_G2D_VRAM_TYPE_2DMAIN:
			GX_LoadOBJ( buf, cgx, siz );
			break;

		case NNS_G2D_VRAM_TYPE_2DSUB:
			GXS_LoadOBJ( buf, cgx, siz );
			break;

		default : GF_ASSERT(0);
	};
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CAP生成 プレート本体
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *	@param	pos_x
 *	@param	pos_y
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static CATS_ACT_PTR CATS_AddCommon( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 pos_x, s16 pos_y, u8 anm, u8 pri )
{
	TCATS_OBJECT_ADD_PARAM_S prm = {
		0, 0, 0,
		0, 1, 0, NNS_G2D_VRAM_TYPE_2DMAIN,
		{ CHR_ID_M_MAIN, PAL_ID_M_MAIN, CEL_ID_MAIN, ANM_ID_MAIN, 0, 0 }, BGPRI_OBJ, FALSE,
	};

	CATS_ACT_PTR cap;

	prm.x = pos_x;
	prm.y = pos_y;
	prm.pri = pri;
	prm.anm = anm;

	cap = CATS_ObjectAdd_S_SubDistance( csp, crp, &prm, CATS_DISTANCE );
	CATS_ObjectAutoAnimeSetCap( cap, TRUE );

	return cap;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	CAP生成 ポケアイコン
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *	@param	pos_x
 *	@param	pos_y
 *	@param	idx
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static CATS_ACT_PTR CATS_AddIcon( CATS_SYS_PTR csp, CATS_RES_PTR crp, s16 pos_x, s16 pos_y, u8 idx )
{
	TCATS_OBJECT_ADD_PARAM_S prm = {
		0, 0, 0,
		0, 0, 0, NNS_G2D_VRAM_TYPE_2DMAIN,
		{ 0, PAL_ID_M_POKEICON, CEL_ID_POKEICON, ANM_ID_POKEICON, 0, 0 }, BGPRI_OBJ, FALSE,
	};

	CATS_ACT_PTR cap;

	GF_ASSERT( idx < PLATE_ID_MAX );

	prm.id[0] = CHR_ID_M_POKEICON_0 + idx;
	prm.x = pos_x;
	prm.y = pos_y;

	cap = CATS_ObjectAdd_S_SubDistance( csp, crp, &prm, CATS_DISTANCE );

	return cap;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート 生成
 *
 *	@param	PLATE_CNT_PTR cnt
 *	@param	pos_x
 *	@param	pos_y
 *	@param	idx
 *	@param	POKEMON_PARAM* pp
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static PLATE_PTR Plate_Create( PLATE_CNT_PTR cnt, s16 pos_x, s16 pos_y, PLATE_ID idx, POKEMON_PARAM* pp )
{
	int i;
	PLATE_PTR plt;
	u8 frm = ( idx == PLATE_ID_FIRST ) ? BG_FRM_M_PLT_0 : BG_FRM_M_PLT_1;
	u8 cx = (pos_x>>3);
	u8 cy = (pos_y>>3);

	plt = sys_AllocMemory( cnt->HeapID, sizeof(PLATE_WORK) );
	MI_CpuClear8( plt, sizeof(PLATE_WORK) );

	// 初期化
	plt->pp = pp;
	plt->pos_x = pos_x;
	plt->pos_y = pos_y;

	// cap 生成
	plt->cap[ PLTCAP_ID_BASE ] = CATS_AddCommon( cnt->csp, cnt->crp, plt->pos_x, plt->pos_y, 0, 1 );
	plt->cap[ PLTCAP_ID_ICON ] = CATS_AddIcon( cnt->csp, cnt->crp, plt->pos_x + PLTPOS_ICON_OFS_X, plt->pos_y + PLTPOS_ICON_OFS_Y, idx );

	// bmpwin 生成
	for( i=0; i<PLTWIN_ID_MAX; i++ )
	{
		const PLTWIN_DAT* dat = &c_PlateWinList[i];

		u8 win_x = cx + dat->pos_x;
		u8 win_y = cy + dat->pos_y;

		GF_BGL_BmpWinAdd( cnt->bgl, &plt->win[i], frm,
				win_x, win_y, dat->siz_x, dat->siz_y,
				dat->palnum, dat->chrnum );
	}

	return plt;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート上に表示する文字列を展開
 *
 *	@param	PLATE_PTR plt
 *	@param	msg_cnt
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Plate_Print( PLATE_PTR plt, MSG_CNT_PTR msg_cnt )
{
	WORDSET* wset = MSG_CNT_GetWordSet( msg_cnt );
	POKEMON_PARAM* pp = plt->pp;
	u32 hp;
	u32 hpmax;

	GF_ASSERT( plt );
	GF_ASSERT( msg_cnt );

	hp = PokeParaGet(pp, ID_PARA_hp, NULL );
	hpmax = PokeParaGet(pp, ID_PARA_hpmax, NULL );

	// name
	WORDSET_RegisterPokeMonsName( wset, 0, PPPPointerGet(pp) );
	MSG_CNT_PrintBmpMessage( msg_cnt, &plt->win[ PLTWIN_ID_NAME ], msg_park_pk_name, 4, 1 );

	// sex
	{
		u32 sexmsg;
		GF_PRINTCOLOR col = COL_BLUE;

		switch( PokeSexGet(pp) )
		{
			case PARA_MALE : sexmsg = msg_park_pk_male; col = COL_BLUE; break;
			case PARA_FEMALE : sexmsg = msg_park_pk_female; col = COL_RED; break;
			case PARA_UNK : sexmsg = msg_park_pk_unk; break;
			default : GF_ASSERT(0);
		}
		MSG_CNT_PrintBmpMessageEx( msg_cnt, &plt->win[ PLTWIN_ID_SEX ], sexmsg, 5, 1, col );
	}

	// lv
	MSG_CNT_PrintBmpNumFont( msg_cnt, &plt->win[ PLTWIN_ID_LV ], PokeParaGet(pp, ID_PARA_level, NULL), 3, TRUE, NUMFONT_MARK_LV );
	// hp
	MSG_CNT_PrintBmpNumFont( msg_cnt, &plt->win[ PLTWIN_ID_HP ], hp, 3, FALSE, NULL );
	// hpmax
	MSG_CNT_PrintBmpNumFont( msg_cnt, &plt->win[ PLTWIN_ID_HPMAX ], hpmax, 3, TRUE, NUMFONT_MARK_SLASH );
	// hpbar
	BmpWin_SetHpBar( &plt->win[ PLTWIN_ID_HPBAR ], hp, hpmax );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート移動初期化
 *
 *	@param	PLATE_PTR plt
 *	@param	move
 *	@param	tar_y
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Plate_MoveStart( PLATE_PTR plt, PLATE_MOVE move, s16 tar_y )
{
	plt->move = move;
	plt->tar_y = tar_y;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート移動処理
 *
 *	@param	PLATE_PTR plt
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Plate_MoveProc( PLATE_PTR plt )
{
	int i;

	GF_BGL_BMPWIN* win;
	GF_BGL_INI* bgl;
	u8 frm;

	s16 now_y;
	s16 abs;
	s16 moveval;

	GF_ASSERT( plt );

	// BG get data
	win = &plt->win[0];
	bgl = GF_BGL_BmpWinGet_BglIni( win );
	frm = GF_BGL_BmpWinGet_Frame( win );

	// pos calc
	now_y = plt->pos_y;
	abs = MATH_ABS( now_y - plt->tar_y );
	moveval = abs >> 2;

	// check end
	if( abs <= 1 || moveval == 0 )
	{
		plt->move = PLATE_MOVE_NULL;
	}
	else
	{
		// move set
		if( now_y > plt->tar_y ) { moveval *= -1; }

		// pos add
		plt->pos_y += moveval;

		if( plt->pos_y < GX_LCD_SIZE_Y + 40 )
		{
			// BG move
			GF_BGL_ScrollReq( bgl, frm, GF_BGL_SCROLL_Y_DEC, moveval );

			// OBJ move
			for(i=0; i<PLTCAP_ID_MAX; i++ )
			{
				s16 cap_x, cap_y;
				CATS_ObjectPosGetCap_SubSurface( plt->cap[i], &cap_x, &cap_y, CATS_DISTANCE );
				cap_y += moveval;
				CATS_ObjectPosSetCap_SubSurface( plt->cap[i], cap_x, cap_y, CATS_DISTANCE );
			}
		}
	}

	HOSAKA_PRINT("[%d] now_y:%d tar_y:%d abs:%d moveval:%d \n",frm, now_y, plt->tar_y, abs, moveval);

	// 転送リクエスト
	GF_BGL_LoadScreenReq( bgl, frm );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート 移動フラグ取得
 *
 *	@param	PLATE_PTR plt
 *
 *	@retval	TRUE:移動してない
 */
//-----------------------------------------------------------------------------
static BOOL Plate_MoveCheck( PLATE_PTR plt )
{
	return ( plt->move == PLATE_MOVE_NULL );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート 削除
 *
 *	@param	PLATE_PTR plt
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void Plate_Delete( PLATE_PTR plt )
{
	int i;

	GF_ASSERT( plt );

	// cap 削除
	for( i=0; i<PLTCAP_ID_MAX; i++ )
	{
		if( plt->cap[i] != NULL )
		{
			CATS_ActorPointerDelete_S( plt->cap[i] );
			plt->cap[i] = NULL;
		}
	}

	// bmpwin 削除
	for( i=0; i<PLTWIN_ID_MAX; i++ )
	{
		GF_BGL_BmpWinOff( &plt->win[i] );
		GF_BGL_BmpWinDel( &plt->win[i] );
	}

	sys_FreeMemoryEz( plt );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート管理 生成
 *
 *	@param	HEAPID HeapID
 *	@param	bgl
 *	@param	msg_cnt
 *	@param	csp
 *	@param	crp
 *	@param	icon_pltt_ofs
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static PLATE_CNT_PTR PlateCnt_Create( HEAPID HeapID, GF_BGL_INI* bgl, MSG_CNT_PTR msg_cnt, CATS_SYS_PTR csp, CATS_RES_PTR crp, s8 icon_pltt_ofs )
{
	PLATE_CNT_PTR cnt;

	cnt = sys_AllocMemory( HeapID, sizeof(PLATE_CNT_WORK) );
	MI_CpuClear8( cnt, sizeof(PLATE_CNT_WORK) );

	cnt->bgl = bgl;
	cnt->HeapID = HeapID;
	cnt->msg_cnt = msg_cnt;
	cnt->csp = csp;
	cnt->crp = crp;
	cnt->icon_pltt_ofs = icon_pltt_ofs;

	return cnt;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート管理 削除
 *
 *	@param	PLATE_CNT_PTR cnt	ワークポインタ
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void PlateCnt_Delete( PLATE_CNT_PTR cnt )
{
	int i;

	GF_ASSERT( cnt );

	for( i=0; i<PLATE_ID_MAX; i++ )
	{
		if( cnt->plate[i] != NULL )
		{
			Plate_Delete( cnt->plate[i] );
		}
	}

	sys_FreeMemoryEz(cnt);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プレート管理 プレート追加
 *
 *	@param	PLATE_CNT_PTR cnt	ワークポインタ
 *	@param	idx					プレートID
 *	@param	pos_x
 *	@param	pos_y
 *	@param	POKEMON_PARAM* pp
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void PlateCnt_Add( PLATE_CNT_PTR cnt, PLATE_ID idx, s16 pos_x, s16 pos_y, POKEMON_PARAM* pp )
{
	PLATE_PTR plt;

	// plate 生成
	plt = Plate_Create( cnt, pos_x, pos_y, idx, pp );

	// pokeicon 転送
	CATS_TransPokeIcon( plt->cap[ PLTCAP_ID_ICON ], plt->pp, cnt->icon_pltt_ofs, cnt->HeapID );

	Plate_Print( plt, cnt->msg_cnt );

	// 保持
	cnt->plate[idx] = plt;
}


//-----------------------------------------------------------------------------
/**
 *	@brief	移動開始
 *
 *	@param	PLATE_CNT_PTR cnt	ワークポインタ
 *	@param	idx					プレートID
 *	@param	move
 *	@param	tar_y
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void PlateCnt_MoveStart( PLATE_CNT_PTR cnt, PLATE_ID idx, PLATE_MOVE move, s16 tar_y )
{
	Plate_MoveStart( cnt->plate[idx], move, tar_y );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	目的地まで移動
 *
 *	@param	PLATE_CNT_PTR cnt	ワークポインタ
 *
 *	@retval	none
 */
//-----------------------------------------------------------------------------
static void PlateCnt_MoveProc( PLATE_CNT_PTR cnt )
{
	int i;

	for( i=0; i<PLATE_ID_MAX; i++)
	{
		if( Plate_MoveCheck( cnt->plate[ i ] ) == FALSE )
		{
			Plate_MoveProc( cnt->plate[ i ] );
		}
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	移動中のプレートがないことを確認
 *
 *	@param	PLATE_CNT_PTR cnt	ワークポインタ
 *
 *	@retval	TRUE:すべて移動は完了している。
 */
//-----------------------------------------------------------------------------
static BOOL PlateCnt_MoveCheck( PLATE_CNT_PTR cnt )
{
	int i;
	BOOL ret = FALSE;

	for( i=0; i<PLATE_ID_MAX; i++ )
	{
		if(	Plate_MoveCheck( cnt->plate[i] ) == FALSE )
		{
			return FALSE;
		}
	}

	return TRUE;
}
